<template>
  <div class="todo-container">
    <!-- 头部区域 -->
    <div class="header">
      <h3>我的待办事项</h3>
      <el-button type="primary" @click="handleAdd">新增事项</el-button>
    </div>

    <!-- 时间线区域 -->
    <el-scrollbar
      ref="timeLineScrollRef"
      class="timeline-wrapper"
      @scroll="handleScroll"
    >
      <div style="width: 100%; overflow: hidden">
        <el-timeline v-if="todoList.length">
          <el-timeline-item
            v-for="item in visibleTodos"
            :key="item.id"
            :timestamp="formatTime(item.createdAt)"
            placement="top"
            :color="item.status === 'done' ? '#67C23A' : '#909399'"
          >
            <el-card shadow="hover" class="todo-card" @click="handleEdit(item)">
              <div class="todo-content">
                <span :class="{ 'done-text': item.status === 'done' }">
                  {{ item.content }}
                </span>
                <el-tag
                  size="small"
                  :type="statusMap[item.status].type"
                  effect="plain"
                >
                  {{ statusMap[item.status].text }}
                </el-tag>
              </div>
            </el-card>
          </el-timeline-item>
        </el-timeline>

        <!-- 加载状态 -->
        <div class="loading-status">
          <span v-show="isLoading">加载中...</span>
          <span v-show="noMore">没有更多了</span>
        </div>
      </div>
    </el-scrollbar>

    <!-- 编辑/新增弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑事项' : '新增事项'"
      width="500px"
    >
      <el-form :model="form" :rules="rules" ref="formRef">
        <el-form-item label="事项内容" prop="content">
          <el-input
            v-model="form.content"
            type="textarea"
            :rows="3"
            placeholder="请输入待办事项内容"
          />
        </el-form-item>
        <el-form-item label="当前状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option
              v-for="(desc, key) in statusMap"
              :key="key"
              :label="desc.text"
              :value="key"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确认</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from "vue";
import dayjs from "dayjs";

const timeLineScrollRef = ref(null);

// 静态数据生成器
const generateMockData = (count = 10) => {
  return Array.from({ length: count }, (_, i) => ({
    id: Date.now() + i,
    content: `待办事项 ${i + 1}`,
    status: ["pending", "processing", "done"][i % 3],
    createdAt: dayjs().subtract(i, "hour").toISOString(),
  }));
};

// 状态管理
const statusMap = {
  pending: { text: "待处理", type: "warning" },
  processing: { text: "进行中", type: "primary" },
  done: { text: "已完成", type: "success" },
};

// 响应式数据
const todoList = ref(generateMockData(20)); // 初始20条测试数据
const visibleCount = ref(5); // 每次加载数量
const loading = ref(false);
const noMore = ref(false);
const dialogVisible = ref(false);
const isEdit = ref(false);
const form = ref({
  id: null,
  content: "",
  status: "pending",
});
const formRef = ref(null);

// 显示的数据（模拟分页）
const visibleTodos = computed(
  () => todoList.value.slice(0, visibleCount.value).reverse() // 按时间倒序
);

// 格式化时间
const formatTime = (time) => {
  return dayjs(time).format("YYYY-MM-DD HH:mm");
};

// 滚动加载
const handleScroll = () => {
  // 优先使用容器引用获取尺寸（更可靠）
  const container = timeLineScrollRef.value?.wrapRef;
  if (!container) return;

  // 获取精确的容器尺寸
  const { scrollTop, clientHeight, scrollHeight } = container;

  // 触发条件判断
  if (
    scrollHeight - scrollTop - clientHeight < 50 && // 距底部50px阈值
    !loading.value &&
    !noMore.value
  ) {
    console.log("触发加载更多");
    loadMore();
  }
};

// 加载更多（模拟）
const loadMore = () => {
  loading.value = true;
  setTimeout(() => {
    visibleCount.value += 5;
    if (visibleCount.value >= todoList.value.length) {
      noMore.value = true;
    }
    loading.value = false;
  }, 800);
};

// 表单验证规则
const rules = {
  content: [
    { required: true, message: "请输入事项内容", trigger: "blur" },
    { min: 3, max: 100, message: "长度在3到100个字符", trigger: "blur" },
  ],
  status: [{ required: true, message: "请选择状态", trigger: "change" }],
};

// 处理新增
const handleAdd = () => {
  form.value = { id: null, content: "", status: "pending" };
  isEdit.value = false;
  dialogVisible.value = true;
};

// 处理编辑
const handleEdit = (item) => {
  form.value = { ...item };
  isEdit.value = true;
  dialogVisible.value = true;
};

// 提交表单
const handleSubmit = async () => {
  await formRef.value.validate();

  if (isEdit.value) {
    // 更新已有项
    const index = todoList.value.findIndex((i) => i.id === form.value.id);
    if (index > -1) {
      todoList.value.splice(index, 1, form.value);
    }
  } else {
    // 新增项
    todoList.value.push({
      ...form.value,
      id: Date.now(),
      createdAt: new Date().toISOString(),
    });
  }

  dialogVisible.value = false;
};

// 初始化加载
onMounted(() => {
  todoList.value.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
});
</script>

<style scoped>
.todo-container {
  padding: 20px;
  width: calc(100% - 40px);
  height: calc(100% - 40px);
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.timeline-wrapper {
  height: calc(100% - 83px);
  padding-right: 15px;
}

.todo-card {
  margin: 8px 0;
  transition: transform 0.2s;
}

.todo-card:hover {
  transform: translateX(5px);
}

.todo-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px;
}

.done-text {
  color: #999;
  text-decoration: line-through;
}

.loading-status {
  padding: 20px 0;
  font-size: 14px;
  color: #666;
  text-align: center;
}

.el-timeline-item__timestamp {
  font-size: 13px;
  color: #666;
  margin-bottom: 8px;
}
</style>
